#include <mockcpp/mockcpp.hpp>
#include <testngpp/testngpp.hpp>
#include <Length.h>
#include <LengthUnit.h>

USING_MOCKCPP_NS
USING_TESTNGPP_NS

FIXTURE(Length)
{
    TEST(should be able to compare 1 mile equals 1760 yards)
    {
        ASSERT_TRUE(Length(1, MILE) == Length(1760, YARD));
    }

    TEST(should be able to compare 1 yard equals 3 feet)
    {
        ASSERT_TRUE(Length(1, YARD) == Length(3, FEET));
    }

    TEST(should be able to check equation of same unit)
    {
        ASSERT_TRUE(Length(1, MILE) != Length(1750, YARD));
        ASSERT_TRUE(Length(1, YARD) != Length(4, FEET));
    }
//New Added Test CASE for add operation
    TEST(should be able to add two lenths equals with big Unit)
    {
        ASSERT_TRUE(Length(1, YARD) + Length(3, FEET) == Length(2, YARD));
	ASSERT_TRUE(Length(1, MILE) + Length(1760, YARD) == Length(2, MILE));
    }

    TEST(should be able to add two lenths equals with small Unit)
    {
        ASSERT_TRUE(Length(1, YARD) + Length(3, FEET) == Length(6, FEET));
	ASSERT_TRUE(Length(1, MILE) + Length(1760, YARD) == Length(3520, YARD));
    }

    TEST(should be able to add two lenths not equals another length)
    {
        ASSERT_TRUE(Length(1, YARD) + Length(3, FEET) != Length(3, YARD));
	ASSERT_TRUE(Length(1, MILE) + Length(1760, YARD) != Length(3530, YARD));
    }
#if 0
//New Added Test CASE for new Length Unit, it should compile error
    TEST(should not be able to compare 2 yard equals 1 meter)
    {
	LengthUnit meter(6);
        ASSERT_TRUE(Length(2, YARD) == Length(1,meter));
    }
#endif
//New Added Test CASE for output to Screen and String
//Test CASE also need refactory
    TEST(Output the Length with new format to Screen)
    {
	std::cout << "Length(0,FEET)" << "==>" << std::endl; 
	Length(0,FEET).toScreen( );
	std::cout << "Length(1,FEET)" << "==>" << std::endl; 
	Length(1,FEET).toScreen( );
	std::cout << "Length(3,FEET)" << "==>" << std::endl; 
	Length(3,FEET).toScreen( );
	std::cout << "Length(4,FEET)" << "==>" << std::endl; 
	Length(4,FEET).toScreen( );
	std::cout << "Length(5280,FEET)" << "==>" << std::endl; 
	Length(5280,FEET).toScreen( );
	std::cout << "Length(5281,FEET)" << "==>" << std::endl; 
	Length(5281,FEET).toScreen( );
	std::cout << "Length(5283,FEET)" << "==>" << std::endl; 
	Length(5283,FEET).toScreen( );
	std::cout << "Length(5284,FEET)" << "==>" << std::endl; 
	Length(5284,FEET).toScreen( );
    }

    TEST(Output the Length with new format to String: Length(0,FEET) ==> "")
    {
	std::ostringstream str;
	Length(0,FEET).toString(str);
	ASSERT_EQ("",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(1,FEET) ==> "1 FEET")
    {
	std::ostringstream str;
	Length(1,FEET).toString(str);
	ASSERT_EQ("1 FEET",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(3,FEET) ==> "1 YARD ")
    {
	std::ostringstream str;
	Length(3,FEET).toString(str);
	ASSERT_EQ("1 YARD ",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(4,FEET) ==> "1 YARD 1 FEET")
    {
	std::ostringstream str;
	Length(4,FEET).toString(str);
	ASSERT_EQ("1 YARD 1 FEET",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(5280,FEET) ==> "1 MILE ")
    {
	std::ostringstream str;
	Length(5280,FEET).toString(str);
	ASSERT_EQ("1 MILE ",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(5281,FEET) ==> "1 MILE 1 FEET")
    {
	std::ostringstream str;
	Length(5281,FEET).toString(str);
	ASSERT_EQ("1 MILE 1 FEET",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(5283,FEET) ==> "1 MILE 1 YARD ")
    {
	std::ostringstream str;
	Length(5283,FEET).toString(str);
	ASSERT_EQ("1 MILE 1 YARD ",str.str( ));
    }
    TEST(Output the Length with new format to String: Length(5284,FEET) ==> "1 MILE 1 YARD 1 FEET")
    {
	std::ostringstream str;
	Length(5284,FEET).toString(str);
	ASSERT_EQ("1 MILE 1 YARD 1 FEET",str.str( ));
    }

//New Added Test CASE
    TEST(Output the Length with new format to String: Length(0,FEET) ==> "0 FEET")
    {
	std::ostringstream str;
	Length(0,FEET).toStringInBaseUnit(str);
	ASSERT_EQ("0 FEET",str.str( ));
    }

    TEST(Output the Length with new format to String: Length(1,FEET) ==> "1 FEET")
    {
	std::ostringstream str;
	Length(1,FEET).toStringInBaseUnit(str);
	ASSERT_EQ("1 FEET",str.str( ));
    }

    TEST(Output the Length with new format to String: Length(1,YARD) ==> "3 FEET")
    {
	std::ostringstream str;
	Length(1,YARD).toStringInBaseUnit(str);
	ASSERT_EQ("3 FEET",str.str( ));
    }

    TEST(Output the Length with new format to String: Length(1,MILE) ==> "5280 FEET")
    {
	std::ostringstream str;
	Length(1,MILE).toStringInBaseUnit(str);
	ASSERT_EQ("5280 FEET",str.str( ));
    }
};

